package com.diploma.project.aiqiyi.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
public class HttpUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    public static String get(String url) throws Exception {
        return get(url, null);
    }

    public static String get(String url, Map<String, String> params) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;

        try {
            if (MapUtils.isNotEmpty(params)) {
                if (!url.contains("?")) {
                    url += "?";
                }

                if (!url.endsWith("&") && !url.endsWith("?")) {
                    url += "&";
                }

                for (Map.Entry<String, String> entry : params.entrySet()) {
                    url += entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), "UTF-8") + "&";
                }
            }

            HttpGet httpGet = new HttpGet(url);
            //add by arison
            //设置请求的报文头部的编码
            //httpGet.setHeader(new BasicHeader("Content-Type", "application/json; charset=utf-8"));

            //设置期望服务端返回的编码
            //httpGet.setHeader(new BasicHeader("Accept", "text/plain;charset=utf-8"));


            logger.info("[GET]request sent, url=" + url);

            long start = System.currentTimeMillis();
            //避免出现超时，如果不配置，httpClient4.3以后默认>24小时
            httpGet.setConfig(getReqeustConfig());
            response = httpClient.execute(httpGet);
            HttpEntity responseEntity = response.getEntity();

            long cost = System.currentTimeMillis() - start;

            String result = EntityUtils.toString(responseEntity, "UTF-8");

            //logger.info("[GET]response received, url=" + url + "cost=" + cost + ", result=" + result);

            return result;
        } finally {
            try {
                httpClient.close();

                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
            }
        }
    }

    /**
     * 发起post请求
     *
     * @param url
     * @param params
     * @return
     * @throws Exception
     */
    public static String post(String url, Map<String, String> params) throws Exception {
        return post(url, params, null);
    }

    public static String postUsercomm(String host, String interfaceUrl, Map<String, String> params, Map<String, String> headers) throws Exception {
        params.put("platform", "mweb");
        params.put("noncestr", "wNMm5S4s2odPj1G4");
        params.put("timestamp", String.valueOf(System.currentTimeMillis()));
        params.put("version", "201");
        String signatureSeed = String.format("noncestr=%s&platform=%s&apiUrl=%s&timestamp=%s",
                params.get("noncestr"), params.get("platform"), interfaceUrl, params.get("timestamp"));
        params.put("sign", DigestUtils.sha1Hex(signatureSeed));
        return post(host + interfaceUrl, params, headers);
    }

    /**
     * 发起post请求
     *
     * @param url
     * @param params
     * @param headers
     * @return
     * @throws Exception
     */
    public static String post(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;

        try {
            HttpPost httpPost = new HttpPost(url);
            if (MapUtils.isNotEmpty(headers)) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }

            List<NameValuePair> httpParams = new ArrayList<>();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                httpParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            httpPost.setEntity(new UrlEncodedFormEntity(httpParams, "UTF-8"));

            logger.info("[POST]url=" + url + ", request param=" + params);
            //避免出现超时，如果不配置，httpClient4.3以后默认>24小时
            httpPost.setConfig(getReqeustConfig());
            response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            String result = EntityUtils.toString(responseEntity, "UTF-8");
            logger.info("[POST]url=" + url + ", response=" + result);

            return result;
        } finally {
            try {
                httpClient.close();

                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
            }
        }
    }

    /**
     * 发起post请求
     *
     * @param url
     * @param params
     * @param headers
     * @return
     * @throws Exception
     */
    public static byte[] postReceiveByte(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;

        try {
            HttpPost httpPost = new HttpPost(url);
            if (MapUtils.isNotEmpty(headers)) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }

            List<NameValuePair> httpParams = new ArrayList<>();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                httpParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            httpPost.setEntity(new UrlEncodedFormEntity(httpParams, "UTF-8"));

            logger.info("[POST]url=" + url + ", request param=" + params);
            //避免出现超时，如果不配置，httpClient4.3以后默认>24小时
            httpPost.setConfig(getReqeustConfig());
            response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            byte[] bytes = EntityUtils.toByteArray(responseEntity);
            return bytes;
        } finally {
            try {
                httpClient.close();

                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
            }
        }
    }

    /**
     * 发起post请求
     *
     * @param url
     * @param entity
     * @return
     * @throws Exception
     */
    public static String post(String url, String entity) throws Exception {
        return post(url, entity, null);
    }

    /**
     * 发起post请求
     *
     * @param url
     * @param entity
     * @param headers
     * @return
     * @throws Exception
     */
    public static String post(String url, String entity, Map<String, String> headers) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;

        try {
            HttpPost httpPost = new HttpPost(url);
            if (MapUtils.isNotEmpty(headers)) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.setHeader(entry.getKey(), entry.getValue());
                }
            }

            StringEntity stringEntity = new StringEntity(entity, "UTF-8");

            httpPost.setEntity(stringEntity);

            logger.info("[POST]url=" + url + ", request stringEntity=" + stringEntity);

            //避免出现超时，如果不配置，httpClient4.3以后默认>24小时
            httpPost.setConfig(getReqeustConfig());
            response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();

            String result = EntityUtils.toString(responseEntity);

            logger.info("[POST]url=" + url + ", response=" + result);

            return result;
        } finally {
            try {
                httpClient.close();

                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
            }
        }
    }


    /**
     * 获取HTTP请求的配置
     *
     * @return String
     */
    public static RequestConfig getReqeustConfig() {
        Integer timeout = 60000;
        //logger.info("Timeout time is:" + timeout);
        //1.ConnectionRequestTimeout: 经历多久之后，这次请求被视为过期
        //2.ConnectTimeout: 等待与服务器建立连接的时间
        //3.SocketTimeout: 与服务器的连接建立了，等待服务器发送数据的时间
        RequestConfig requstConfigure = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build();
        return requstConfigure;
    }


    public static JSONObject executeHttpPatch(String url, JSONObject jsonParam) {
        JSONObject resultObj = new JSONObject();
        HttpClient httpClient = new DefaultHttpClient();
        HttpPatch httpPatch = new HttpPatch(url);
        httpPatch.setHeader("Content-type", "application/json");
        httpPatch.setHeader("Charset", "utf-8");
        httpPatch.setHeader("Accept", "application/json");
        httpPatch.setHeader("Accept-Charset", "utf-8");
        try {
            if (jsonParam != null) {
                StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
                httpPatch.setEntity(entity);
            }
            HttpResponse response = httpClient.execute(httpPatch);
            int statusCode = response.getStatusLine().getStatusCode();
            logger.debug(" patch request code is  : " + statusCode);
            resultObj.put("statusCode", statusCode);
        } catch (ParseException | IOException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
        return resultObj;
    }
}
